/**
 * Project: apollo-base-dal
 * 
 * File Created at 2016年5月6日
 * 
 * Copyright 2015-2016 dx.com Croporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * DongXue software Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with dx.com.
 */
package com.dx.pf.dal.jdbc.sql;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.dx.pf.dal.Logger;
import com.dx.pf.dal.constants.DalConstant;

/**
 * @ClassName: SqlUpdate
 * @Description: 更新语句的helper
 * @author wuzhenfang(wzfbj2008@163.com)
 * @date 2016年5月6日 上午10:27:06
 * @version V1.0
 */
public class SqlHelperUpdate extends SqlOperator {

	private final static Logger logger = Logger.getLogger(SqlHelperUpdate.class);

	/** 更新sql */
	private StringBuilder updatesql = new StringBuilder(128);

	/** set部分 */
	private StringBuilder setsql = new StringBuilder(64);

	/** where部分 */
	private StringBuilder wheresql = new StringBuilder(64);

	private Map<String, Object> setParamMap = new HashMap<String, Object>();
	private Map<String, Object> whereParamMap = new HashMap<String, Object>();

	public boolean isSetValue = false;// 是否设置值

	public SqlHelperUpdate(SqlHelper sqlHelper, Class<?> clazz) {
		super(sqlHelper, clazz);
		super.sql = new StringBuilder("UPDATE ");
	}

	public SqlHelperUpdate setUpdate(Map<String, Object> columnValueMap) {
		if (columnValueMap != null && columnValueMap.size() > 0) {
			setParamMap = columnValueMap;
//			processNamedPerprotyMap(columnValueMap);
			processSetNamedPerprotyMap(columnValueMap);
			isSetValue = true;// 设置更新值成功后置状态
		} else {
			throw new NullPointerException("更新的map对象为null。");
		}
		return this;
	}

	/**
	 * 设置where条件
	 * @param condi
	 * @return
	 */
	public SqlHelperUpdate setWhere(Condition condition) {
		wheresql = new StringBuilder(64);
		wheresql.append(DalConstant.sql_Where).append(condition.getCondiSQL());
		whereParamMap = condition.getConditionParam();
//		processNamedPerprotyMap(whereParamMap);
		processWhereNamedPerprotyMap(whereParamMap);
		return this;
	}

	/**
	 * 处理Set值的冲突
	 * @param paramMap
	 */
	private void processSetNamedPerprotyMap(Map<String, Object> paramMap) {
		Map<String, Object> newConditionMapParam = new HashMap<String, Object>();
		boolean isChange = false;
		if(wheresql.length() > 0){
			newConditionMapParam.putAll(setParamMap);
		}
		for (Iterator<Entry<String, Object>> itr = paramMap.entrySet().iterator(); itr.hasNext();) {
			Entry<String, Object> entry = itr.next();
			String columnName = entry.getKey();
			if(wheresql.length() > 0 && whereParamMap.get(columnName) != null){
				if (!isChange) {
					isChange = true;
				}
				Object value = setParamMap.get(columnName);
				newConditionMapParam.remove(columnName);
				String keyStr = new StringBuilder(columnName).append("_").append(0).toString();// 循环后冲突的新字段名称
				if (setsql.length() > 0) {
					setsql.append(DalConstant.sql_pause);
				}
				setsql.append(columnName).append(DalConstant.sql_eq).append(DalConstant.sql_colon).append(keyStr).append(DalConstant.sql_spaces);
				newConditionMapParam.put(keyStr, value);
			}else{
				if (setsql.length() > 0) {
					setsql.append(DalConstant.sql_pause);
				}
				setsql.append(columnName).append(DalConstant.sql_eq).append(DalConstant.sql_colon).append(columnName).append(DalConstant.sql_spaces);
			}
		}
		if (isChange) {
			setParamMap = newConditionMapParam;
		}
	}
	
	/**
	 * 处理where值的冲突
	 * @param paramMap
	 */
	private void processWhereNamedPerprotyMap(Map<String, Object> paramMap) {
		Map<String, Object> newConditionMapParam = new HashMap<String, Object>();
		newConditionMapParam.putAll(setParamMap);
		String replacesql = setsql.toString();
		boolean isChange = false;
		for (Iterator<Entry<String, Object>> itr = paramMap.entrySet().iterator(); itr.hasNext();) {
			Entry<String, Object> entry = itr.next();
			String columnName = entry.getKey();
			if (isSetValue && setParamMap.containsKey(columnName)) {// 设置过Set
				if (!isChange) {
					isChange = true;
				}
				Object value = setParamMap.get(columnName);
				newConditionMapParam.remove(columnName);
				String keyStr = new StringBuilder(columnName).append("_").append(0).toString();// 循环后冲突的新字段名称
				String olderstr = new StringBuilder(DalConstant.sql_colon).append(columnName).append(DalConstant.sql_spaces).toString();
				String newstr = new StringBuilder(DalConstant.sql_colon).append(keyStr).append(DalConstant.sql_spaces).toString();
				replacesql = replacesql.replaceFirst(olderstr, newstr);
				setsql = new StringBuilder(replacesql.replaceFirst(olderstr, newstr));
				newConditionMapParam.put(keyStr, value);
			}
		}
		if (isChange) {
			setsql = new StringBuilder(replacesql);
			setParamMap = newConditionMapParam;
		}
	}
	/**
	 * 处理map中name有重复值
	 * @param paramMap
	 */
	@SuppressWarnings("unused")
	@Deprecated
	private void processNamedPerprotyMap(Map<String, Object> paramMap) {
		Map<String, Object> newConditionMapParam = new HashMap<String, Object>();
		int setMapSize = setParamMap.size();
		// 处理两个条件中字段重复问题
		if (setMapSize > 0) {// 设置更新值
			newConditionMapParam.putAll(setParamMap);
			for (Iterator<Entry<String, Object>> itr = paramMap.entrySet().iterator(); itr.hasNext();) {
				Entry<String, Object> entry = itr.next();
				String columnName = entry.getKey();
				String replacesql = setsql.toString();
				if (setParamMap.containsKey(columnName) || (replacesql.length() > 0 && whereParamMap.containsKey(columnName))) {
					Object value = setParamMap.get(columnName);
					if ((isSetValue && null != value)) {
						newConditionMapParam.remove(columnName);
						String keyStr = new StringBuilder(columnName).append("_").append(0).toString();// 循环后冲突的新字段名称
						String olderstr = new StringBuilder(DalConstant.sql_colon).append(columnName).append(DalConstant.sql_spaces).toString();
						String newstr = new StringBuilder(DalConstant.sql_colon).append(keyStr).append(DalConstant.sql_spaces).toString();
						setsql = new StringBuilder(replacesql.replaceFirst(olderstr, newstr));
						newConditionMapParam.put(keyStr, value);
					} else if (!isSetValue && null != whereParamMap.get(columnName) && null != value) {
						newConditionMapParam.remove(columnName);
						String keyStr = new StringBuilder(columnName).append("_").append(0).toString();// 循环后冲突的新字段名称
						if (setsql.length() > 0) {
							setsql.append(DalConstant.sql_pause);
						}
						setsql.append(columnName).append(DalConstant.sql_eq).append(DalConstant.sql_colon).append(keyStr).append(DalConstant.sql_spaces);
						newConditionMapParam.put(keyStr, value);
					} else if (null != value) {
						if (setsql.length() > 0) {
							setsql.append(DalConstant.sql_pause);
						}
						setsql.append(columnName).append(DalConstant.sql_eq).append(DalConstant.sql_colon).append(columnName).append(DalConstant.sql_spaces);
					}
				}
			}
			setParamMap = newConditionMapParam;
		}
	}

	@Override
	protected void putAllexecuteMap(Map<String, Object> paramMap) {
		setParamMap.putAll(whereParamMap);
		super.executeMap = setParamMap;
	}

	@Override
	public SqlHelper builder() {
		if (!isSetValue) {
			logger.error("未设置更新的值。");
			throw new NullPointerException("未设置更新的值。");
		}
		updatesql.append(super.tableName).append(DalConstant.sql_set);
		updatesql.append(setsql).append(wheresql);
		super.sql.append(updatesql);
		putAllexecuteMap(null);
		logger.debug(updatesql.toString());
		return super.sqlHelper;
	}

}
